//-----------------------------------------------------------------------------
//  Copyright (C) 2005-2008 Thomas S. Ullrich 
//
//  This file is part of the Solitaire Mahjong project.
//
//  This file may be used under the terms of the GNU General Public License.
//  This project is free software; you can redistribute it and/or modify it
//  under the terms of the GNU General Public License.
//  
//  Author: Thomas S. Ullrich
//  Last update: October 28, 2007
//-----------------------------------------------------------------------------
#include <QSettings>
#include <QDir>
#include <QDesktopWidget>
#include "smSettings.h"
#include "smDefinitions.h"
#include "smVersion.h"
#include "smHighscoreList.h"
#include <iostream>

using namespace std;

//
//  Define default settings for all preferences
//
smSettings*   smSettings::mInstance = 0;
const int     smSettings::mDefaultTileSize = medium;
#if defined(Q_OS_WIN32)
const QColor  smSettings::mDefaultBackgroundColor = QColor(0x00, 0x90, 0x00);
#else
const QColor  smSettings::mDefaultBackgroundColor = QColor(0x00, 0x75, 0x00);
#endif
const bool    smSettings::mDefaultShowTileNamesInStatusBar = true;
const bool    smSettings::mDefaultBeepWhenTileNotFree = false;
const bool    smSettings::mDefaultRandomHint = false;
const bool    smSettings::mDefaultShowNumberOfPossibleMoves = false;
const QString smSettings::mDefaultLastVisitedDirectory = QDir::homePath();
const QPoint  smSettings::mDefaultMainWindowPosition = QPoint(100,25);
const QPoint  smSettings::mDefaultPreferencesWindowPosition = QPoint(200,50);
const QPoint  smSettings::mDefaultHighscoreWindowPosition = QPoint(300,75);
const QPoint  smSettings::mDefaultPlayedTilesWindowPosition = QPoint(400,100);
const QPoint  smSettings::mDefaultHelpBrowserPosition = QPoint(400,125);
const QSize   smSettings::mDefaultPlayedTilesWindowSize = QSize(300,400);

smSettings* smSettings::instance()
{
    if (!mInstance) mInstance = new smSettings;
    return mInstance;
}

smSettings::smSettings()
{
    mSettings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, "tu", "SolitaireMahjong");
    mHighscoreList = 0;
}

void smSettings::setHighscoreList(smHighscoreList* list)
{
    if (list) mHighscoreList = list;
}

void smSettings::load()
{
    mSettings->beginGroup("/SolitaireMahjong");
    mSettings->beginGroup("/Preferences");
    mCurrentTileSize = mSettings->value("/TileSize", medium).toInt();
    int r = mSettings->value("/BackgroundColor/red", mDefaultBackgroundColor.red()).toInt();
    int g = mSettings->value("/BackgroundColor/green", mDefaultBackgroundColor.green()).toInt();
    int b = mSettings->value("/BackgroundColor/blue", mDefaultBackgroundColor.blue()).toInt();
    mBackgroundColor = QColor(r, g, b);
    mShowTileNamesInStatusBar = mSettings->value("/ShowTileNamesInStatusBar", mDefaultShowTileNamesInStatusBar).toBool();
    mBeepWhenTileNotFree = mSettings->value("/BeepWhenTileNotFree", mDefaultBeepWhenTileNotFree).toBool();
    mRandomHint = mSettings->value("/RandomHint", mDefaultRandomHint).toBool();
    mShowNumberOfPossibleMoves = mSettings->value("/ShowNumberOfMoves", mDefaultShowNumberOfPossibleMoves).toBool();
    mLastVisitedDirectory = mSettings->value("/LastVistedDirectory", mDefaultLastVisitedDirectory).toString();
    mSettings->endGroup();
    if (mHighscoreList) {
        mSettings->beginGroup("/HighScores");
        mHighscoreList->load(mSettings); // class knows how to read its own content best
        mSettings->endGroup();
    }
    mMainWindowPosition = mSettings->value("/Geometry/MainWindowPosition", mDefaultMainWindowPosition).toPoint();
    mPreferencesWindowPosition = mSettings->value("/Geometry/PreferencesWindowPosition", mDefaultPreferencesWindowPosition).toPoint();
    mHighscoreWindowPosition = mSettings->value("/Geometry/HighscoreWindowPosition", mDefaultHighscoreWindowPosition).toPoint();
    mPlayedTilesWindowPosition = mSettings->value("/Geometry/PlayedTilesWindowPosition", mDefaultPlayedTilesWindowPosition).toPoint();
    mHelpBrowserPosition = mSettings->value("/Geometry/HelpBrowserPosition", mDefaultHelpBrowserPosition).toPoint();
    mPlayedTilesWindowSize = mSettings->value("/Geometry/PlayedTilesWindowSize", mDefaultPlayedTilesWindowSize).toSize();
    mSettings->endGroup();
}

void smSettings::save()
{
    mSettings->beginGroup("/SolitaireMahjong");
    mSettings->setValue("/Version", VERSION_NUMBER);  // ignored so far (but good to have it)
    mSettings->beginGroup("/Preferences");
    mSettings->setValue("/TileSize", mCurrentTileSize);
    mSettings->setValue("/BackgroundColor/red", mBackgroundColor.red());
    mSettings->setValue("/BackgroundColor/green", mBackgroundColor.green());
    mSettings->setValue("/BackgroundColor/blue", mBackgroundColor.blue());
    mSettings->setValue("/ShowTileNamesInStatusBar", mShowTileNamesInStatusBar);
    mSettings->setValue("/BeepWhenTileNotFree", mBeepWhenTileNotFree);
    mSettings->setValue("/RandomHint", mRandomHint);
    mSettings->setValue("/ShowNumberOfMoves", mShowNumberOfPossibleMoves);
    mSettings->setValue("/LastVistedDirectory", mLastVisitedDirectory);
    mSettings->endGroup();
    if (mHighscoreList) {
        mSettings->beginGroup("/HighScores");
        mHighscoreList->save(mSettings);  // class knows how to write its own content best
        mSettings->endGroup();
    }
    
    //
    // Check for odd window positions that make the window disappear or unmovable.
    // While this always can be fixed it might worry the non-expert user. Here we
    // make sure the left upper position of the window is always in the available
    // desktop. This can also happen if the settings got corrupted. 
    // Available desktop geometry might not be the full desktop size because of
    // menu and navigation bars etc.
    // If the position is off we set it back to the default.
    //
    QRect rect = QApplication::desktop()->availableGeometry();
    if (mMainWindowPosition.x() < rect.topLeft().x() || mMainWindowPosition.x() > rect.topRight().x() ||
        mMainWindowPosition.y() < rect.topLeft().y() || mMainWindowPosition.y() > rect.bottomLeft().y())
        mMainWindowPosition = mDefaultMainWindowPosition;
    if (mPreferencesWindowPosition.x() < rect.topLeft().x() || mPreferencesWindowPosition.x() > rect.topRight().x() ||
        mPreferencesWindowPosition.y() < rect.topLeft().y() || mPreferencesWindowPosition.y() > rect.bottomLeft().y())
        mPreferencesWindowPosition = mDefaultPreferencesWindowPosition;
    if (mHighscoreWindowPosition.x() < rect.topLeft().x() || mHighscoreWindowPosition.x() > rect.topRight().x() ||
        mHighscoreWindowPosition.y() < rect.topLeft().y() || mHighscoreWindowPosition.y() > rect.bottomLeft().y())
        mHighscoreWindowPosition = mDefaultHighscoreWindowPosition;
    if (mPlayedTilesWindowPosition.x() < rect.topLeft().x() || mPlayedTilesWindowPosition.x() > rect.topRight().x() ||
        mPlayedTilesWindowPosition.y() < rect.topLeft().y() || mPlayedTilesWindowPosition.y() > rect.bottomLeft().y())
        mPlayedTilesWindowPosition = mDefaultPlayedTilesWindowPosition;
    if (mHelpBrowserPosition.x() < rect.topLeft().x() || mHelpBrowserPosition.x() > rect.topRight().x() ||
        mHelpBrowserPosition.y() < rect.topLeft().y() || mHelpBrowserPosition.y() > rect.bottomLeft().y())
        mHelpBrowserPosition = mDefaultHelpBrowserPosition;
    
    mSettings->setValue("/Geometry/MainWindowPosition", mMainWindowPosition);
    mSettings->setValue("/Geometry/PreferencesWindowPosition", mPreferencesWindowPosition);
    mSettings->setValue("/Geometry/HighscoreWindowPosition", mHighscoreWindowPosition);
    mSettings->setValue("/Geometry/PlayedTilesWindowPosition", mPlayedTilesWindowPosition);
    mSettings->setValue("/Geometry/HelpBrowserPosition", mHelpBrowserPosition);
    mSettings->setValue("/Geometry/PlayedTilesWindowSize", mPlayedTilesWindowSize);
    mSettings->endGroup();
    
    //
    // Recreate instance of QSettings. Why? Because
    // the preferences are only written to file when
    // the destructor is called, but smSettings is a
    // soliton class.
    //
    delete mSettings; mSettings = 0;
    mSettings = new QSettings();
}

void smSettings::setDefault()
{
    mBackgroundColor = mDefaultBackgroundColor;
    mCurrentTileSize = mDefaultTileSize;
    mShowTileNamesInStatusBar = mDefaultShowTileNamesInStatusBar;
    mBeepWhenTileNotFree = mDefaultBeepWhenTileNotFree;
    mRandomHint = mDefaultRandomHint;
    mShowNumberOfPossibleMoves = mDefaultShowNumberOfPossibleMoves;
    mLastVisitedDirectory = mDefaultLastVisitedDirectory;
    mMainWindowPosition = mDefaultMainWindowPosition;
    mPreferencesWindowPosition = mDefaultPreferencesWindowPosition;
    mHighscoreWindowPosition = mDefaultHighscoreWindowPosition;
    mPlayedTilesWindowPosition = mDefaultPlayedTilesWindowPosition;
    mHelpBrowserPosition = mDefaultHelpBrowserPosition;
    mPlayedTilesWindowSize = mDefaultPlayedTilesWindowSize;
    
}

